import { HttpException, HttpStatus, Inject, Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
import { Repository } from 'typeorm';
import { Role } from './entities/role.entity';
import { RedisService } from '../redis/redis.service';
import { RegisterDto } from './dto/register.dto';
import { md5 } from '../utils';
import { EmailService } from '../email/email.service';
import { LoginDto } from './dto/login.dto';
import { LoginUserVo } from './vo/login-user.vo';
import { Permission } from './entities/permission.entity';
import { UpdateUserDto } from './dto/update-user.dto';

@Injectable()
export class UserService {
  @InjectRepository(User)
  private userRepository: Repository<User>;

  @InjectRepository(Role)
  private roleRepository: Repository<Role>;

  @InjectRepository(Permission)
  private permissionRepository: Repository<Permission>;

  @Inject(RedisService)
  private redisService: RedisService;

  @Inject(EmailService)
  private emailService: EmailService;

  async initData() {
    const user1 = new User();
    user1.username = 'zhangsan';
    user1.password = md5('111111');
    user1.email = 'xxx@xx.com';
    user1.isAdmin = true;
    user1.nickName = '张三';
    user1.phoneNumber = '13233323333';

    const user2 = new User();
    user2.username = 'lisi';
    user2.password = md5('222222');
    user2.email = 'yy@yy.com';
    user2.nickName = '李四';

    const role1 = new Role();
    role1.name = '管理员';

    const role2 = new Role();
    role2.name = '普通用户';

    const permission1 = new Permission();
    permission1.code = 'ccc';
    permission1.description = '访问 ccc 接口';

    const permission2 = new Permission();
    permission2.code = 'ddd';
    permission2.description = '访问 ddd 接口';

    user1.roles = [role1];
    user2.roles = [role2];

    role1.permissions = [permission1, permission2];
    role2.permissions = [permission1];

    await this.permissionRepository.save([permission1, permission2]);
    await this.roleRepository.save([role1, role2]);
    await this.userRepository.save([user1, user2]);
  }

  async register(user: RegisterDto) {
    // 验证码
    // 先查是否有此用户
    // 没有就插入

    const captcha = await this.redisService.get(`captcha_${user.email}`);
    if (!captcha) {
      throw new HttpException('验证码已失效', HttpStatus.BAD_REQUEST);
    }
    if (user.captcha !== captcha) {
      throw new HttpException('验证码错误', HttpStatus.BAD_REQUEST);
    }
    const foundUser = await this.userRepository.findOneBy({
      username: user.username,
    });

    if (foundUser) {
      throw new HttpException('用户已存在', HttpStatus.BAD_REQUEST);
    }
    const registerUser = new User();
    registerUser.email = user.email;
    registerUser.password = md5(user.password);
    registerUser.username = user.username;
    registerUser.nickName = user.nickName;
    registerUser.headPic = user.headPic
    try {
      await this.userRepository.save(registerUser);
      return '注册成功';
    } catch (error) {
      console.log(error, UserService);
      return '注册失败';
    }
  }

  async login(loginDto: LoginDto) {
    const user = await this.userRepository.findOne({
      where: {
        username: loginDto.username,
      },
      relations: ['roles', 'roles.permissions', 'blogs', 'stars', 'dailys', 'likes'],
    });
    if (!user) {
      throw new HttpException('该用户名未注册', HttpStatus.BAD_REQUEST);
    }
    const password = md5(loginDto.password);
    if (password !== user.password) {
      throw new HttpException('密码错误', HttpStatus.BAD_REQUEST);
    }
    const vo = new LoginUserVo();
    vo.userInfo = {
      id: user.id,
      username: user.username,
      nickName: user.nickName,
      email: user.email,
      phoneNumber: user.phoneNumber,
      headPic: user.headPic,
      createTime: user.createTime.getTime(),
      isFrozen: user.isFrozen,
      isAdmin: user.isAdmin,
      roles: user.roles.map((item) => item.name),
      // blogs: user.blogs,
      // stars: user.stars,
      // dailys: user.dailys,
      // likes: user.likes,
      permissions: user.roles.reduce((arr, item) => {
        item.permissions.forEach((permission) => {
          if (arr.indexOf(permission) === -1) {
            arr.push(permission);
          }
        });
        return arr;
      }, []),
    };
    console.log(vo.userInfo);
    return vo;
  }

  async findUserById(userId: number, isAdmin: boolean) {
    const user = await this.userRepository.findOne({
      where: {
        id: userId,
        isAdmin,
      },
      relations: ['roles', 'roles.permissions'],
    });

    return {
      id: user.id,
      username: user.username,
      isAdmin: user.isAdmin,
      roles: user.roles.map((item) => item.name),
      permissions: user.roles.reduce((arr, item) => {
        item.permissions.forEach((permission) => {
          if (arr.indexOf(permission) === -1) {
            arr.push(permission);
          }
        });
        return arr;
      }, []),
    };
  }

  async updateUser (updateUserDto: UpdateUserDto) {
    console.log()
    const user = await this.userRepository.findOneBy({
      id: updateUserDto.id
    })
    if(!user) {
      throw new HttpException('用户不存在', HttpStatus.BAD_REQUEST)
    }
    updateUserDto.headPic ? user.headPic = updateUserDto.headPic : ''
    updateUserDto.nickName ? user.nickName = updateUserDto.nickName : ''
    updateUserDto.isFrozen ? user.isFrozen = updateUserDto.isFrozen : ''

    return await this.userRepository.save(user)
  }

  async getUserInfo (id: number) {
    const user = await this.userRepository.findOne({
      where: {
        id:id
      },
      select: ['nickName', 'id', 'isFrozen', 'username', 'headPic']
    })

    return user
  }
}
